package cn.learn.designpattern.strategy;

import java.math.BigDecimal;

/**
 * 策略模式:
 * 【定义】策略模式定义了一系列的算法，并将每一个算法封装起来，而且使他们可以相互替换，让算法独立于使用它的客户而独立变化。
 *
 * 【使用场景】
 * 1.针对同一类型问题的多种处理方式，仅仅是具体行为有差别时；
 * 2.需要安全地封装多种同一类型的操作时；
 * 3.出现同一抽象类有多个子类，而又需要使用 if-else 或者 switch-case 来选择具体子类时。
 *
 *
 * 客户埋单计算总价格
 * @author huangyezhan
 * @date 2018/11/20-23:36
 */
public class Payment {

    /**
     * 客户本次消费的总金额
     */
    private BigDecimal totalAmount = BigDecimal.ZERO;

    /**
     * 某种商品的总价格
     */
    private BigDecimal amount = BigDecimal.ZERO;

    /**
     * 每个客户都有一个计算价格的策略，初始都是普通计算，即原价
     */
    private SalePrice salePrice = null;

    /**
     * 客户购买，就会增加它的总额
     * @param amount    客户购买某种商品的总价格
     */
    public void buy(BigDecimal amount) {
        this.amount = amount;
        totalAmount = totalAmount.add(amount);
        /* 变化点，我们将策略的制定转移给了策略工厂，将这部分责任分离出去 */

        //salePrice = SalePriceFactory.createSalePrice(this);
    }

    /**
     * 计算客户最终要付的钱
     * @return
     */
    public BigDecimal doPayment() {
        SalePriceFactory instance = SalePriceFactory.getInstance();
        salePrice = instance.createSalePrice(totalAmount);
        return salePrice.salePrice(totalAmount);
    }

}
